package o2o.config;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * 使用切面获取参数
 */
@Component
//@Aspect
@Slf4j
public class RequestParameterAop {

    // 系统环境变量
    @Autowired
    private Environment environment;

    /**
     * @Description: 定义需要拦截的切面
     * @Return: void
     **/
    @Pointcut("execution(* o2o.web.actions..*.*(..))")
    public void methodArgs() {

    }

    @Around("methodArgs()")
    public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
        boolean flag = environment.acceptsProfiles("dev", "test");
        if (!flag) {
            return joinPoint.proceed();
        }
        Object result = null;
        Signature signature = joinPoint.getSignature();
        // 方法名
        String methodName = signature.getName();
        // 类名
        String serviceName = signature.getDeclaringTypeName();

        // 请求的url
        String url = "";
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            url = requestAttributes.getRequest().getRequestURI();
        }
        // 参数名数组
        String[] parameterNames = ((MethodSignature) signature).getParameterNames();
        // 构造参数组集合
        List<Object> argList = new ArrayList<>();
        for (Object arg : joinPoint.getArgs()) {
            // request/response无法使用toJSON
            if (arg instanceof HttpServletRequest) {
                argList.add("request");
            } else if (arg instanceof HttpServletResponse) {
                argList.add("response");
            } else {
                argList.add(JSON.toJSON(arg));
            }
        }
        try {
            log.info("{}-->{} -> 方法({}) -> 参数:{} - {}", url, serviceName, methodName, JSON.toJSON(parameterNames), JSON.toJSON(argList));
        } catch (Exception e) {
            log.error("参数获取失败: {}", e.getMessage());
        }
        result = joinPoint.proceed();

        return result;
    }
}